package cn.mitool.crypto.digest;

import cn.mitool.core.util.ByteUtil;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;

/**
 * SM3摘要
 *
 * @author dragon
 * @version 1.0
 * @date 2024/7/2 11:28
 */
public class SM3 {

    static {
        // 添加Bouncy Castle作为安全提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * SHA-512摘要
     *
     * @param data 数据
     * @return SHA-512哈希值
     */
    public String digestHex(String data) throws NoSuchAlgorithmException, NoSuchProviderException {
        /* Java SM3 */
        MessageDigest messageDigest = MessageDigest.getInstance("SM3", "BC");
        messageDigest.update(data.getBytes(StandardCharsets.UTF_8));
        // 计算哈希值并转换为16进制字符串
        byte[] digest = messageDigest.digest();
        return ByteUtil.byteToHexString(digest);
    }

    /**
     * SHA-512摘要
     *
     * @param data 数据
     * @return SHA-512哈希值
     */
    public String digestHex(byte[] data) throws NoSuchAlgorithmException, NoSuchProviderException {
        /* Java SM3 */
        MessageDigest messageDigest = MessageDigest.getInstance("SM3", "BC");
        messageDigest.update(data);
        // 计算哈希值并转换为16进制字符串
        byte[] digest = messageDigest.digest();
        return ByteUtil.byteToHexString(digest);
    }

    /**
     * SHA-512摘要
     *
     * @param data 数据
     * @return SHA-512哈希值
     */
    public String digestHex(InputStream data) throws NoSuchAlgorithmException, NoSuchProviderException, IOException {
        /* Java SM3 */
        MessageDigest messageDigest = MessageDigest.getInstance("SM3", "BC");
        messageDigest.update(data.readAllBytes());
        // 计算哈希值并转换为16进制字符串
        byte[] digest = messageDigest.digest();
        return ByteUtil.byteToHexString(digest);
    }

    /**
     * 返回长度为32位的加密后的byte数组
     *
     * @param dataByte 待加密的byte数组
     * @return 加密后的byte数组
     */
    public static byte[] getEncryptByDataByte(byte[] dataByte) {
        SM3Digest sm3 = new SM3Digest();
        sm3.update(dataByte, 0, dataByte.length);
        byte[] encryptByte = new byte[sm3.getDigestSize()];
        sm3.doFinal(encryptByte, 0);
        return encryptByte;
    }

}
